import requests
import re
import json
import logging
from collections import Counter, defaultdict
from datetime import datetime
from config.settings import get_config
from zai import ZhipuAiClient

class AIService:
    """AI分析服务"""
    
    def __init__(self, config=None):
        if config is None:

            config = get_config()
        
        ai_config = config.get_ai_config()
        self.api_key = ai_config.get('api_key', "sk-d8b48b0fcd5e4ee7823d7ce71db41fde")
        self.api_url = ai_config.get('api_url', "https://api.deepseek.com/v1/chat/completions")
        self.model = ai_config.get('model', "deepseek-chat")
    
    def analyze_lottery_data(self, lottery_data, custom_prompt=""):
        """分析双色球数据"""
        try:
            # 添加调试日志
            print(f"[DEBUG] AI服务接收到的custom_prompt: '{custom_prompt}'")
            
            # 检查API密钥
            # if not self.api_key or self.api_key == "sk-vecbuswjvujawumjjjfeecmpuqakkhsyresyjdrlrboiouwq":
            #     print("[WARNING] 使用默认API密钥，可能无法正常工作")
            
            # 准备数据
            data_text = self._prepare_data_for_analysis(lottery_data)
            
            # 构建提示词
            prompt = self._build_analysis_prompt(data_text, custom_prompt)
            
            # 调用AI接口
            # response = self._call_deepseek_api(prompt)
            response = self._call_zhipu_api(prompt)
            # 解析AI响应
            predictions, analysis_content = self.parse_ai_response(response)
            
            return {
                'analysis': analysis_content,
                'predictions': predictions,
                'analysis_details': {
                    'predictions': predictions,
                    'analysis': analysis_content
                }
            }
            
        except Exception as e:
            logging.error(f"AI分析失败: {str(e)}")
            # 返回本地分析结果作为备用
            return self._generate_local_analysis(lottery_data, custom_prompt)
    
    def verify_prediction(self, predicted_numbers, actual_result):
        """验证预测结果"""
        try:
            win_info = []
            total_amount = 0
            
            actual_red_balls = actual_result.get_red_balls()
            actual_blue_ball = actual_result.blue_ball
            
            for i, prediction in enumerate(predicted_numbers):
                red_balls = prediction.get('red_balls', [])
                blue_ball = prediction.get('blue_ball')
                
                # 计算红球匹配数
                red_matches = len(set(red_balls) & set(actual_red_balls))
                blue_match = blue_ball == actual_blue_ball
                
                # 判断中奖等级
                level, amount = self._calculate_prize(red_matches, blue_match)
                
                if level:
                    win_info.append(f"第{i+1}组: {level} {amount}元")
                    total_amount += amount
                else:
                    win_info.append(f"第{i+1}组: 未中奖")
            
            return {
                'win_info': '; '.join(win_info),
                'win_amount': total_amount,
                'total_groups': len(predicted_numbers)
            }
            
        except Exception as e:
            logging.error(f"验证预测结果失败: {str(e)}")
            raise
    
    def _prepare_data_for_analysis(self, lottery_data):
        """准备分析数据"""
        data_lines = []
        for result in lottery_data:
            red_balls = result.get_red_balls()
            data_lines.append(
                f"{result.draw_number}: {result.draw_date} - "
                f"红球: {red_balls[0]:02d} {red_balls[1]:02d} {red_balls[2]:02d} "
                f"{red_balls[3]:02d} {red_balls[4]:02d} {red_balls[5]:02d} "
                f"蓝球: {result.blue_ball:02d}"
            )
        return "\n".join(data_lines)
    
    def _build_analysis_prompt(self, data_text, custom_prompt=""):
        """构建分析提示词"""
        # 添加调试日志
        # print(f"[DEBUG] 构建提示词时使用的custom_prompt: '{custom_prompt}'")
        
        base_prompt = f"""双色球规则：
开奖时间
每周二、四、日21:15开奖；每周三期，开奖号码通过摇奖方式产生，中国教育电视台对开奖进行现场直播。
玩法说明
双色球投注区分为红球号码区和蓝球号码区，红球号码范围为01～33，蓝球号码范围为01～16。双色球每期从33个红球中开出6个号码，从16个蓝球中开出1个号码作为中奖号码，双色球玩法即是竞猜开奖号码的6个红球号码和1个蓝球号码，顺序不限。
设奖及中奖
一等奖：中6+1，高等奖奖金的75%与奖池奖金之和除以中奖注数。
二等奖：中6+0，高等奖奖金的25%除以中奖注数。
三等奖：中5+1，3000元。
四等奖：中5+0、中4+1，200元。
五等奖：中4+0、中3+1，10元。
六等奖：中2+1、中1+1、中0+1，5元。

你是一个双色球投注专家，擅长双色球选号、杀号，预测下一期双色球数据。

根据以下历史开奖数据，{custom_prompt if custom_prompt else '分析红球的杀号规律和选号规律'}，并提供5组号码预测下一期的中奖：

{data_text}

请按照以下格式返回分析结果：
1. 杀号分析：分析哪些号码可以杀掉
2. 选号分析：分析哪些号码可以选择
3. 预测号码：提供5组号码，每组包含6个红球和1个蓝球
4. 分析依据：说明预测的依据和理由

预测号码格式：
[
  {{"red_balls": [1,2,3,4,5,6], "blue_ball": 1}},
  {{"red_balls": [7,8,9,10,11,12], "blue_ball": 2}},
  ...
]"""
        print(f"[DEBUG] 最终发给AI的提示词是base_prompt: '{base_prompt}'")
        return base_prompt
    
    def _call_zhipu_api(self, prompt):
        "调用智普ai"
        try:
            client = ZhipuAiClient(api_key="78d056ad6e3745e09f6c1f60a9291e37.rSUMZT7YPIQ1PHDF")

            # 创建聊天完成请求
            response = client.chat.completions.create(
                model="glm-4.5",
                messages=[
                    {
                        "role": "user",
                        "content": prompt
                    }
                ],
                temperature=0.7,
                top_p=0.8
            )
            result = response.json()
            print('智普ai返回的数据为：'+result)
            return result
        except Exception as e:
            logging.error(f"调用智普ai失败: {str(e)}")
            raise


    def _call_deepseek_api(self,prompt):
            """调用DeepSeek API"""
            try:
                # 这里应该使用真实的DeepSeek API密钥
                # 为了演示，我们使用模拟响应
                api_key = "sk-d8b48b0fcd5e4ee7823d7ce71db41fde"  # 需要替换为真实的API密钥

                headers = {
                    "Authorization": f"Bearer {api_key}",
                    "Content-Type": "application/json"
                }

                data = {
                    "model": "deepseek-chat",
                    "messages": [
                        {"role": "user", "content": prompt}
                    ],
                    "temperature": 0.7,
                    "max_tokens": 8192
                }

                # 设置更长的超时时间
                timeout = 90  # 90秒超时

                print(f"[DEBUG] 开始调用DeepSeek API，超时时间: {timeout}秒")

                # 模拟API调用（实际使用时取消注释下面的代码）
                response = requests.post("https://api.deepseek.com/v1/chat/completions",
                                         headers=headers, json=data, timeout=timeout)

                print(f"[DEBUG] DeepSeek API响应状态: {response.status_code}")
                result = response.json()
                return result

            except requests.exceptions.Timeout:
                print(f"DeepSeek API调用超时")
                raise Exception("AI分析超时，请稍后重试")
            except requests.exceptions.RequestException as e:
                print(f"DeepSeek API网络错误: {e}")
                raise Exception(f"AI服务网络错误: {str(e)}")
            except Exception as e:
                print(f"DeepSeek API调用失败: {e}")
                raise e


    def parse_ai_response(self, response):
        """解析AI响应，兼容字符串或OpenAI样式字典响应"""
        try:
            # 兼容不同返回结构：字符串/标准字典/其他
            if isinstance(response, str):
                content = response
            elif isinstance(response, dict):
                try:
                    content = (
                        response.get('choices', [{}])[0]
                        .get('message', {})
                        .get('content', '')
                    )
                except Exception:
                    content = ''
                if not content:
                    # 兜底：若模型直接返回content字段或其它结构
                    content = response.get('content') or response.get('text') or ''
                if not content:
                    import json as _json
                    content = _json.dumps(response, ensure_ascii=False)
            else:
                content = str(response)
            print(f"[DEBUG] AI响应内容: {content}")
            
            # 解析预测号码
            predictions = []
            lines = content.split('\n')
            
            for line in lines:
                line = line.strip()
                print(f"[DEBUG] 解析行: {line}")
                
                # 尝试多种格式匹配
                if '第' in line and ('组:' in line or '组：' in line):
                    print(f"[DEBUG] 找到组行: {line}")
                    
                    # 解析红球 - 尝试多种格式
                    red_balls = []
                    
                    # 格式1: 红球[1,2,3,4,5,6]
                    red_match = re.search(r'红球\[([^\]]+)\]', line)
                    if red_match:
                        try:
                            red_balls = [int(x.strip()) for x in red_match.group(1).split(',') if x.strip().isdigit()]
                            print(f"[DEBUG] 格式1匹配成功: {red_balls}")
                        except Exception as e:
                            print(f"[DEBUG] 格式1解析失败: {e}")
                    
                    # 格式2: 红球 1 2 3 4 5 6
                    if not red_balls:
                        red_match = re.search(r'红球\s*(\d+)\s*(\d+)\s*(\d+)\s*(\d+)\s*(\d+)\s*(\d+)', line)
                        if red_match:
                            try:
                                red_balls = [int(red_match.group(i)) for i in range(1, 7)]
                                print(f"[DEBUG] 格式2匹配成功: {red_balls}")
                            except Exception as e:
                                print(f"[DEBUG] 格式2解析失败: {e}")
                    
                    # 格式3: 红球: 1,2,3,4,5,6
                    if not red_balls:
                        red_match = re.search(r'红球[:：]\s*([\d,\s]+)', line)
                        if red_match:
                            try:
                                red_balls = [int(x.strip()) for x in red_match.group(1).split(',') if x.strip().isdigit()]
                                print(f"[DEBUG] 格式3匹配成功: {red_balls}")
                            except Exception as e:
                                print(f"[DEBUG] 格式3解析失败: {e}")
                    
                    # 格式4: 直接匹配数字序列 [1,2,3,4,5,6]
                    if not red_balls:
                        red_match = re.search(r'\[(\d+,\d+,\d+,\d+,\d+,\d+)\]', line)
                        if red_match:
                            try:
                                red_balls = [int(x.strip()) for x in red_match.group(1).split(',')]
                                print(f"[DEBUG] 格式4匹配成功: {red_balls}")
                            except Exception as e:
                                print(f"[DEBUG] 格式4解析失败: {e}")
                    
                    # 解析蓝球 - 尝试多种格式
                    blue_ball = None
                    
                    # 格式1: 蓝球04
                    blue_match = re.search(r'蓝球(\d+)', line)
                    if blue_match:
                        try:
                            blue_ball = int(blue_match.group(1))
                            print(f"[DEBUG] 蓝球格式1匹配成功: {blue_ball}")
                        except Exception as e:
                            print(f"[DEBUG] 蓝球格式1解析失败: {e}")
                    
                    # 格式2: 蓝球: 04
                    if not blue_ball:
                        blue_match = re.search(r'蓝球[:：]\s*(\d+)', line)
                        if blue_match:
                            try:
                                blue_ball = int(blue_match.group(1))
                                print(f"[DEBUG] 蓝球格式2匹配成功: {blue_ball}")
                            except Exception as e:
                                print(f"[DEBUG] 蓝球格式2解析失败: {e}")
                    
                    # 格式3: 直接匹配蓝球数字
                    if not blue_ball:
                        blue_match = re.search(r',蓝球(\d+)', line)
                        if blue_match:
                            try:
                                blue_ball = int(blue_match.group(1))
                                print(f"[DEBUG] 蓝球格式3匹配成功: {blue_ball}")
                            except Exception as e:
                                print(f"[DEBUG] 蓝球格式3解析失败: {e}")
                    
                    # 验证红球和蓝球的有效性
                    if red_balls and len(red_balls) == 6:
                        # 检查红球范围 (1-33)
                        valid_reds = all(1 <= ball <= 33 for ball in red_balls)
                        # 检查红球是否有重复
                        unique_reds = len(set(red_balls)) == 6
                        
                        if valid_reds and unique_reds and blue_ball and 1 <= blue_ball <= 16:
                            predictions.append({
                                'red_balls': sorted(red_balls),  # 确保红球排序
                                'blue_ball': blue_ball
                            })
                            print(f"[DEBUG] 添加预测: 红球{sorted(red_balls)}, 蓝球{blue_ball}")
                        else:
                            print(f"[DEBUG] 验证失败: 红球{red_balls}(有效:{valid_reds},唯一:{unique_reds}), 蓝球{blue_ball}")
                    else:
                        print(f"[DEBUG] 红球解析失败: {red_balls}")
            
            print(f"[DEBUG] 最终预测数量: {len(predictions)}")
            
            # 如果没有解析到任何预测，使用备选方案
            if not predictions:
                print("[DEBUG] 未解析到预测数据，使用备选方案")
                fallback_predictions = self._generate_fallback_predictions()
                return fallback_predictions, content
            
            # 解析分析说明
            analysis = ""
            for line in lines:
                if '分析说明：' in line or line.strip().startswith(('1.', '2.', '3.', '4.')):
                    analysis += line + '\n'
            
            return predictions, content
        except Exception as e:
            print(f"解析AI响应失败: {e}")
            import traceback
            traceback.print_exc()
            fallback_predictions = self._generate_fallback_predictions()
            return fallback_predictions, "解析失败，使用备选方案"
    
    def _calculate_prize(self, red_matches, blue_match):
        """计算中奖等级和金额"""
        if red_matches == 6 and blue_match:
            return "一等奖", 5000000  # 简化处理，实际金额需要根据奖池计算
        elif red_matches == 6 and not blue_match:
            return "二等奖", 100000  # 简化处理
        elif red_matches == 5 and blue_match:
            return "三等奖", 3000
        elif (red_matches == 5 and not blue_match) or (red_matches == 4 and blue_match):
            return "四等奖", 200
        elif (red_matches == 4 and not blue_match) or (red_matches == 3 and blue_match):
            return "五等奖", 10
        elif (red_matches == 2 and blue_match) or (red_matches == 1 and blue_match) or (red_matches == 0 and blue_match):
            return "六等奖", 5
        else:
            return None, 0
    
    def _generate_fallback_predictions(self):
        """生成备选预测号码"""
        import random
        predictions = []
        for i in range(5):
            # 生成随机红球号码
            red_balls = sorted(random.sample(range(1, 34), 6))
            # 生成随机蓝球号码
            blue_ball = random.randint(1, 16)
            predictions.append({
                'red_balls': red_balls,
                'blue_ball': blue_ball
            })
        return predictions
    
    def _generate_local_analysis(self, lottery_data, custom_prompt=""):
        """生成本地分析结果（AI服务不可用时的备用方案）"""
        try:
            # 统计红球出现频率
            red_ball_counts = {}
            blue_ball_counts = {}
            
            for result in lottery_data:
                red_balls = result.get_red_balls()
                for ball in red_balls:
                    red_ball_counts[ball] = red_ball_counts.get(ball, 0) + 1
                blue_ball_counts[result.blue_ball] = blue_ball_counts.get(result.blue_ball, 0) + 1
            
            # 找出高频和低频号码
            sorted_red = sorted(red_ball_counts.items(), key=lambda x: x[1], reverse=True)
            sorted_blue = sorted(blue_ball_counts.items(), key=lambda x: x[1], reverse=True)
            
            # 生成预测号码
            predictions = []
            for i in range(5):
                # 选择高频红球
                high_freq_reds = [ball for ball, count in sorted_red[:15]]
                # 选择低频红球
                low_freq_reds = [ball for ball, count in sorted_red[-15:]]
                
                # 混合选择
                selected_reds = []
                for j in range(6):
                    if j < 3:
                        # 前3个选择高频
                        if high_freq_reds:
                            selected_reds.append(high_freq_reds[j % len(high_freq_reds)])
                    else:
                        # 后3个选择低频
                        if low_freq_reds:
                            selected_reds.append(low_freq_reds[(j-3) % len(low_freq_reds)])
                
                # 去重并确保6个号码
                selected_reds = list(set(selected_reds))[:6]
                while len(selected_reds) < 6:
                    selected_reds.append(sorted_red[len(selected_reds) % len(sorted_red)][0])
                
                # 选择蓝球
                blue_ball = sorted_blue[i % len(sorted_blue)][0] if sorted_blue else 1
                
                predictions.append({
                    'red_balls': sorted(selected_reds),
                    'blue_ball': blue_ball
                })
            
            # 生成分析文本
            analysis_text = f"""基于{len(lottery_data)}期历史数据的本地分析结果：

红球频率分析：
- 高频号码（出现{len(lottery_data)//3}次以上）：{[ball for ball, count in sorted_red[:10]]}
- 低频号码（出现较少）：{[ball for ball, count in sorted_red[-10:]]}

蓝球频率分析：
- 高频蓝球：{[ball for ball, count in sorted_blue[:5]]}

预测策略：结合高频号码的稳定性和低频号码的回补性，提供5组号码预测。

{custom_prompt if custom_prompt else '分析完成'}"""
            
            return {
                'analysis': analysis_text,
                'predictions': predictions,
                'analysis_details': {
                    'predictions': predictions,
                    'analysis': analysis_text,
                    'method': 'local_analysis'
                }
            }
            
        except Exception as e:
            logging.error(f"本地分析失败: {str(e)}")
            return {
                'analysis': f'基于{len(lottery_data)}期历史数据的分析结果（AI服务暂时不可用）',
                'predictions': [],
                'analysis_details': {
                    'predictions': [],
                    'analysis': f'基于{len(lottery_data)}期历史数据的分析结果',
                    'method': 'fallback'
                }
            } 